package com.zt.dev.physicalequipment.service.impl;

import com.zt.dev.physicalequipment.mapper.PhysicalEquipmentMapper;
import com.zt.dev.physicalequipment.mapper.PhysicalEquipmentMessageMapper;
import com.zt.dev.physicalequipment.mapper.PhysicalTypeMapper;
import com.zt.dev.physicalequipment.mapper.PhysicalTypeValueMapper;
import com.zt.dev.physicalequipment.pojo.*;
import com.zt.dev.physicalequipment.service.PhysicalEquipmentService;
import com.zt.dev.physicalequipment.utils.BeanUtil;
import com.zt.dev.physicalequipment.utils.ExcelUtil;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PhysicalEquipmentServiceImpl implements PhysicalEquipmentService {

    @Autowired
    private PhysicalEquipmentMapper equipmentMapper;
    @Autowired
    private PhysicalEquipmentMessageMapper messageMapper;
    @Autowired
    private PhysicalTypeMapper typeMapper;
    @Autowired
    private PhysicalTypeValueMapper valueMapper;

    @Override
    public List<PhysicalEquipment> getAllEquipment() {
        return equipmentMapper.getAll();
    }

    @Override
    public int register(MessageDTO messageDTO) {
        PhysicalEquipmentMessage message = messageDTO.getMessage();
        int result = messageMapper.insert(message);
        if (result == 1) {
            List<PhysicalTypeValue> values = messageDTO.getValues();
            for (PhysicalTypeValue value : values) {
                value.setMessageId(message.getId());
                valueMapper.insert(value);
            }
        }
        return result;
    }

    @Override
    public int insertEquipment(EquipmentDTO equipment) {
        PhysicalEquipment physicalEquipment = new PhysicalEquipment();
        physicalEquipment.setEquipmentName(equipment.getEquipmentName());
        int result = equipmentMapper.insert(physicalEquipment);
        if (result == 1) {
            List<PhysicalType> typeList = equipment.getTypes();
            int count = 0;
            for (PhysicalType physicalType : typeList) {
                physicalType.setEquipmentId(physicalEquipment.getId());
                count += typeMapper.insert(physicalType);
            }
            if (count != typeList.size()) {
                result = 0;
            }
        }
        return result;
    }

    @Override
    public int updateEquipmentMessage(PhysicalEquipmentMessage equipment) {
        if (equipment.getId() == null) {
            return 0;
        }
        int result = messageMapper.update(equipment);
        return result;
    }

    @Override
    public List<PhysicalType> getTypesByEquipment(Integer equipmentId) {
        return typeMapper.getByeId(equipmentId);
    }

    @Override
    public List<PhysicalEquipmentMessage> getMessageByEquipment(Integer equipmentId) {
        return messageMapper.getByEquipment(equipmentId);
    }

    @Override
    public List<PhysicalTypeValue> getValueBymId(Integer id) {
        return valueMapper.getBymId(id);
    }

    @Override
    public PhysicalTypeValue getValueBymIdAndtId(Integer messageId, Integer typeId) {
        return valueMapper.getBymIdAndtId(messageId, typeId);
    }

    @Override
    public PageBean<PhysicalEquipmentMessage> getAllEquipmentMessage(int currentPage, int pageSize) {
        int count = messageMapper.getCount();
        PageBean<PhysicalEquipmentMessage> pageBean = PageBean.pageCommon(count, currentPage, pageSize);
        // 起始 结束 页
        int start = (currentPage - 1) * pageBean.getPageSize();
        int end = pageBean.getPageSize();
        pageBean.setLists(messageMapper.getAll(start, end));
        return pageBean;
    }

    @Override
    public List<PhysicalEquipmentMessage> copy(Integer[] ids) {
        List<PhysicalEquipmentMessage> messageList = new ArrayList<>();
        for (Integer id : ids) {
            PhysicalEquipmentMessage message = messageMapper.getById(id);
            List<PhysicalTypeValue> valueList = valueMapper.getBymId(message.getId());
            int result = messageMapper.insert(message);
            if (result == 1) {
                messageList.add(message);
                if (valueList != null && valueList.size() != 0) {
                    for (PhysicalTypeValue value : valueList) {
                        value.setMessageId(message.getId());
                        valueMapper.insert(value);
                    }
                }
            }
        }
        return messageList;
    }

    @Override
    public List<PhysicalEquipmentMessage> getAllEquipmentMessageWithoutPageBean() {
        return messageMapper.getAllWithoutPageBean();
    }

    @Override
    public int deleteMessages(Integer[] ids) {
        int result = 0;
        for (Integer id : ids) {
            result += messageMapper.delete(id);
        }
        return result;
    }

    @Override
    public MessageDTO getMessageDetail(Integer id) {
        PhysicalEquipmentMessage message = messageMapper.getById(id);
        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setMessage(message);
        List<PhysicalTypeValue> values = valueMapper.getBymId(id);
        for (PhysicalTypeValue value : values) {
            String name = typeMapper.getById(value.getTypeId()).getTypeName();
            value.setTypeName(name);
        }
        messageDTO.setValues(values);
        // TODO log
        return messageDTO;
    }

    @Override
    public HSSFWorkbook export() {
        HSSFWorkbook wb = new HSSFWorkbook();
        List<PhysicalEquipment> equipmentList = getAllEquipment();
        for (PhysicalEquipment equipment : equipmentList) {
            String sheetName = equipment.getEquipmentName();
            List<PhysicalEquipmentMessage> messageList = getMessageByEquipment(equipment.getId());
            List<PhysicalType> typeList = getTypesByEquipment(equipment.getId());

            String typeString = "主要性能," + typeList.size() + ",1";

            List<List<String>> headerList = getHeader(typeString, typeList);
            List<String> title1 = headerList.get(0);
            List<String> title2 = headerList.get(1);

            List<List<String>> column = new ArrayList<>();
            for (PhysicalEquipmentMessage message : messageList) {
                if (message == null) {
                    break;
                }
                column.add(getColumn(message, typeList));
            }
            try {
                wb = ExcelUtil.getHSSFWorkbook(wb, sheetName, title1, title2, column);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return wb;
    }

    @Override
    public HSSFWorkbook exportHeader() {
        List<PhysicalEquipment> equipmentList = getAllEquipment();
        HSSFWorkbook wb = new HSSFWorkbook();
        for (PhysicalEquipment equipment : equipmentList) {
            String sheetName = equipment.getEquipmentName();
            List<PhysicalEquipmentMessage> messageList = getMessageByEquipment(equipment.getId());
            List<PhysicalType> typeList = getTypesByEquipment(equipment.getId());

            String typeString = "主要性能," + typeList.size() + ",1";

            List<List<String>> headerList = getHeader(typeString, typeList);
            List<String> title1 = headerList.get(0);
            List<String> title2 = headerList.get(1);

            try {
                wb = ExcelUtil.getHSSFWorkbook(wb, sheetName, title1, title2, null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return wb;
    }

    @Override
    public HSSFWorkbook exportByIds(Integer[] ids) {
        HSSFWorkbook wb = new HSSFWorkbook();
        List<Integer> equipmentList = messageMapper.getEquipmentIdsByIds(ids);
        Map<Integer, List<PhysicalEquipmentMessage>> data = new HashMap<>();
        for (Integer equipmentId : equipmentList) {
            List<PhysicalEquipmentMessage> thisIdList = new ArrayList<>();
            for (Integer id : ids) {
                PhysicalEquipmentMessage message = messageMapper.getById(id);
                if (message.getEquipmentId() == equipmentId) {
                    thisIdList.add(message);
                }
            }
            data.put(equipmentId, thisIdList);
        }
        for (Integer equipmentId : data.keySet()) {
            PhysicalEquipment equipment = equipmentMapper.getById(equipmentId);
            String sheetName = equipment.getEquipmentName();
            List<PhysicalEquipmentMessage> messageList = data.get(equipmentId);
            List<PhysicalType> typeList = getTypesByEquipment(equipment.getId());

            String typeString = "主要性能," + typeList.size() + ",1";

            List<List<String>> headerList = getHeader(typeString, typeList);
            List<String> title1 = headerList.get(0);
            List<String> title2 = headerList.get(1);

            List<List<String>> column = new ArrayList<>();
            for (PhysicalEquipmentMessage message : messageList) {
                if (message == null) {
                    break;
                }
                column.add(getColumn(message, typeList));
            }
            try {
                wb = ExcelUtil.getHSSFWorkbook(wb, sheetName, title1, title2, column);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return wb;
    }

    /**
     * 生成表头
     * 
     * @param typeString
     * @param typeList
     * @return
     */
    private List<List<String>> getHeader(String typeString, List<PhysicalType> typeList) {
        List<List<String>> headerList = new ArrayList<>(2);
        List<String> title1 = new ArrayList<>();
        title1.add("序号,1,2");
        title1.add("装备信息,5,1");
        title1.add(typeString);
        title1.add("接口信息,2,1");
        title1.add("使用信息,4,1");
        headerList.add(title1);
        List<String> title2 = new ArrayList<>();
        title2.add("实物装备名称");
        title2.add("装备类型");
        title2.add("装备编号");
        title2.add("研制单位");
        title2.add("所属部队");
        for (PhysicalType type : typeList) {
            title2.add(type.getTypeName());
        }
        title2.add("输入参数");
        title2.add("输出参数");
        title2.add("使用状态");
        title2.add("使用地址");
        title2.add("开始使用时间");
        title2.add("使用结束时间");
        headerList.add(title2);
        return headerList;
    }

    /**
     * 生成一条表数据
     * 
     * @param message
     * @param typeList
     * @return
     */
    private List<String> getColumn(PhysicalEquipmentMessage message, List<PhysicalType> typeList) {
        BeanUtil.nullToEmpty(message);
        List<String> result = new ArrayList<>();
        result.add(message.getName());
        result.add(message.getType());
        result.add(message.getNumber());
        result.add(message.getUnit());
        result.add(message.getForces());
        for (PhysicalType type : typeList) {
            PhysicalTypeValue value = getValueBymIdAndtId(message.getId(), type.getId());
            if (value != null) {
                result.add(value.getTypeValue());
            } else {
                result.add("");
            }
        }
        result.add(message.getInParams());
        result.add(message.getOutParams());
        result.add(message.getState());
        result.add(message.getLocation());
        result.add(message.getLocationStartTime());
        result.add(message.getLocationEndTime());
        return result;
    }

    @Override
    public boolean importPhysical(MultipartFile file) {  
        int count = 0;      
        try {
            Map<String,List<List<String>>> data = ExcelUtil.importData(file);
            for (String equipmentName : data.keySet()) {
                PhysicalEquipment equipment = equipmentMapper.getByName(equipmentName);
                if (equipment != null && data.get(equipmentName).size() > 1) {
                    count += insertList(data.get(equipmentName), equipment);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (count == 0) {
            return false;
        }
        return true;
    }

    private int insertList(List<List<String>> data,PhysicalEquipment equipment) {
        int count = 0;
        List<String> title = data.get(0);
        for (int i = 1 ; i < data.size() ; i ++) {
            List<String> one = data.get(i);
            int typeNum = one.size() - 12;
            PhysicalEquipmentMessage message = new PhysicalEquipmentMessage();
            message.setName(one.get(1));
            message.setType(one.get(2));
            message.setNumber(one.get(3));
            message.setUnit(one.get(4));
            message.setForces(one.get(5));
            message.setInParams(one.get(5 + typeNum + 1));
            message.setOutParams(one.get(5 + typeNum + 2));
            message.setState(one.get(5 + typeNum + 3));
            message.setLocation(one.get(5 + typeNum + 4));
            message.setStartTime(one.get(5 + typeNum + 5));
            message.setEndTime(one.get(5 + typeNum + 6));
            message.setEquipmentId(equipment.getId());
            count += messageMapper.insert(message);
            for (int j = 6 ; j < 6 + typeNum ; j ++) {
                PhysicalType type = typeMapper.getByNameAndeId(title.get(j),equipment.getId());
                if (type != null) {
                    PhysicalTypeValue value = new PhysicalTypeValue();
                    value.setMessageId(message.getId());
                    value.setTypeId(type.getId());
                    value.setTypeValue(one.get(j));
                    valueMapper.insert(value);
                }
            }
        }
        return count;
    }
}
